/** TTY functions to catch button and joystick events
 *
 * This file contains functions to catch events from buttons and the joystick.
*/
//##############################################################################




/** PIN declarations */
#include "board.h"
//------------------------------------------------------------------------------




/** GPIO functions to set and clear interrupt flags */
#include "gpio.h"
//------------------------------------------------------------------------------




/** Interrupt handling to be able to register interrupt handlers */
#include "intc.h"
//------------------------------------------------------------------------------




/** To provide a ringbuffer with button and joystick events. */
#include "LR_ringbuffer.h"
//------------------------------------------------------------------------------




/** Definition of event ids */
#include "LR_tty.h"
//##############################################################################




/** Buffer to store events */
LR_ringbuffer * buffer;
//##############################################################################




/** Interrupt handler to catch button events */
__attribute__((__interrupt__))
static void button_handler( void )
{
  if (gpio_get_pin_interrupt_flag( GPIO_PUSH_BUTTON_0 ))
  {
    LR_ringbuffer_put( buffer, LR_TTY_PB0 );
    gpio_clear_pin_interrupt_flag( GPIO_PUSH_BUTTON_0 );
  }
  else if (gpio_get_pin_interrupt_flag( GPIO_PUSH_BUTTON_1 ))
  {
    LR_ringbuffer_put( buffer, LR_TTY_PB1 );
    gpio_clear_pin_interrupt_flag( GPIO_PUSH_BUTTON_1 );
  }
  else if (gpio_get_pin_interrupt_flag( GPIO_PUSH_BUTTON_2 ))
  {
    LR_ringbuffer_put( buffer, LR_TTY_PB2 );
    gpio_clear_pin_interrupt_flag( GPIO_PUSH_BUTTON_2 );
  }
}
//------------------------------------------------------------------------------




/** Interrupt handler to catch joystick events */
__attribute__((__interrupt__))
static void joystick_handler( void )
{
  if (gpio_get_pin_interrupt_flag( GPIO_JOYSTICK_UP ))
  {
    LR_ringbuffer_put( buffer, LR_TTY_UP );
    gpio_clear_pin_interrupt_flag( GPIO_JOYSTICK_UP );
  }
  else if (gpio_get_pin_interrupt_flag( GPIO_JOYSTICK_DOWN ))
  {
    LR_ringbuffer_put( buffer, LR_TTY_DOWN );
    gpio_clear_pin_interrupt_flag( GPIO_JOYSTICK_DOWN );
  }
  else if (gpio_get_pin_interrupt_flag( GPIO_JOYSTICK_LEFT ))
  {
    LR_ringbuffer_put( buffer, LR_TTY_LEFT );
    gpio_clear_pin_interrupt_flag( GPIO_JOYSTICK_LEFT );
  }
  else if (gpio_get_pin_interrupt_flag( GPIO_JOYSTICK_RIGHT ))
  {
    LR_ringbuffer_put( buffer, LR_TTY_RIGHT );
    gpio_clear_pin_interrupt_flag( GPIO_JOYSTICK_RIGHT );
  }
  else if (gpio_get_pin_interrupt_flag( GPIO_JOYSTICK_PUSH ))
  {
    LR_ringbuffer_put( buffer, LR_TTY_PUSH );
    gpio_clear_pin_interrupt_flag( GPIO_JOYSTICK_PUSH );
  }
}
//------------------------------------------------------------------------------




/** Initialisation routine
 *
 * This function must be called before using the tty functionality. It sets up
 * the required interrupt handlers and redirects events to the given buffer.
 *
 * \parm buf The ringbuffer to store events.
*/
void LR_tty_init( LR_ringbuffer * buf )
{
  buffer = buf;

  gpio_enable_pin_interrupt( GPIO_PUSH_BUTTON_0, GPIO_RISING_EDGE );
  gpio_enable_pin_interrupt( GPIO_PUSH_BUTTON_1, GPIO_RISING_EDGE );
  gpio_enable_pin_interrupt( GPIO_PUSH_BUTTON_2, GPIO_RISING_EDGE );
 Disable_global_interrupt( );
  INTC_register_interrupt( &button_handler,
      AVR32_GPIO_IRQ_0 + (GPIO_PUSH_BUTTON_0 / 8), AVR32_INTC_INT1 );
  INTC_register_interrupt( &button_handler,
      AVR32_GPIO_IRQ_0 + (GPIO_PUSH_BUTTON_1 / 8), AVR32_INTC_INT1 );
  INTC_register_interrupt( &button_handler,
      AVR32_GPIO_IRQ_0 + (GPIO_PUSH_BUTTON_2 / 8), AVR32_INTC_INT1 );
Enable_global_interrupt( );


    gpio_enable_pin_interrupt( GPIO_JOYSTICK_UP, GPIO_FALLING_EDGE );
  gpio_enable_pin_interrupt( GPIO_JOYSTICK_DOWN, GPIO_FALLING_EDGE );
  gpio_enable_pin_interrupt( GPIO_JOYSTICK_RIGHT, GPIO_FALLING_EDGE );
  gpio_enable_pin_interrupt( GPIO_JOYSTICK_PUSH, GPIO_FALLING_EDGE );
  gpio_enable_pin_interrupt( GPIO_JOYSTICK_LEFT, GPIO_FALLING_EDGE );


  Disable_global_interrupt( );
   INTC_register_interrupt( &joystick_handler,
      AVR32_GPIO_IRQ_0 + (GPIO_JOYSTICK_UP / 8), AVR32_INTC_INT1 );
  INTC_register_interrupt( &joystick_handler,
      AVR32_GPIO_IRQ_0 + (GPIO_JOYSTICK_DOWN / 8), AVR32_INTC_INT1 );
  INTC_register_interrupt( &joystick_handler,
      AVR32_GPIO_IRQ_0 + (GPIO_JOYSTICK_LEFT / 8), AVR32_INTC_INT1 );
  INTC_register_interrupt( &joystick_handler,
      AVR32_GPIO_IRQ_0 + (GPIO_JOYSTICK_RIGHT / 8), AVR32_INTC_INT1 );
  INTC_register_interrupt( &joystick_handler,
      AVR32_GPIO_IRQ_0 + (GPIO_JOYSTICK_PUSH / 8), AVR32_INTC_INT1 );
  Enable_global_interrupt( );

}
//##############################################################################




